﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text;

namespace MyTime.CsvProvider
{
    /// <summary>
    /// Helper class to parse the information
    /// </summary>
    public class CsvHelper
    {
        #region constructor
        /// <summary>
        /// Will setup a list of rows for the csv file. Every change to the CsvData object will be written to disk
        /// </summary>
        /// <param name="filePath">The path of the file</param>
        /// <param name="delimiter">the delimiter of the csv columns</param>
        public CsvHelper(string filePath, char delimiter, int skipHeader = 0)
        {
            if (!File.Exists(filePath))
                throw new FileNotFoundException("CSV file not found", filePath);
            string[] rows = System.IO.File.ReadAllLines(filePath);
            BindingList<string[]> rowArr = new BindingList<string[]>();
            foreach (string row in rows.Skip(skipHeader))
            {
                string[] cols = row.Split(delimiter);
                rowArr.Add(cols);
            }
            this.FilePath = filePath;
            this.Delimiter = delimiter;
            this.CsvData = rowArr;
            this.CsvData.ListChanged += CsvData_ListChanged;
        }
        /// <summary>
        /// When the list changes we write the new changes to the file
        /// Becasue the list is always default we never have to do two way sync
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void CsvData_ListChanged(object sender, ListChangedEventArgs e)
        {
            string[] arr = CsvData.Select(row => string.Join(Delimiter.ToString(), row)).ToArray();
            System.IO.File.WriteAllLines(FilePath, arr);
        }
        #endregion

        #region methods
        /// <summary>
        /// Updates the csv file with new data
        /// </summary>
        /// <param name="newRow">the new row to replace its existing row</param>
        /// <param name="colHeaderMatchPos">specific column value to match</param>
        public void UpdateRow(string[] newRow, params int[] colHeaderMatchPos)
        {
            int rowNr = 0;
            foreach (var row in CsvData)
            {
                bool match = true;
                foreach (var colHeader in colHeaderMatchPos)
                {
                    if (row[colHeader] != newRow[colHeader])
                    {
                        match = false;
                        break;
                    }
                }
                if (match)
                {
                    CsvData.RemoveAt(rowNr);
                    CsvData.Insert(rowNr, newRow);
                    break;
                }
                rowNr++;
            }
        }
        /// <summary>
        /// Add a new row to the collection
        /// </summary>
        /// <param name="newRow"></param>
        public void AddRow(string[] newRow)
        {
            CsvData.Add(newRow);
        }
        /// <summary>
        /// Gets the rownumber for a certain row
        /// </summary>
        /// <param name="rowToFind"></param>
        /// <returns></returns>
        public int GetRowNr(string[] rowToFind)
        {
            return CsvData.IndexOf(rowToFind);
        }
        /// <summary>
        /// Gets the csv data 
        /// </summary>
        /// <returns></returns>
        public BindingList<string[]> GetCsvData()
        {
            return CsvData;
        }
        #endregion

        #region properties

        public BindingList<string[]> CsvData { get; private set; }

        public string FilePath { get; private set; }

        public char Delimiter { get; private set; }

        #endregion
    }
}
